package cn.duli.xianer.controller;

import cn.duli.xianer.pojo.MyResult;
import cn.duli.xianer.pojo.UserLoginAuths;
import cn.duli.xianer.pojo.Users;
import cn.duli.xianer.service.UserLoginAuthsService;
import cn.duli.xianer.service.UsersService;
import cn.duli.xianer.utils.JWTUtil;
import cn.duli.xianer.utils.MD5Util;
import cn.duli.xianer.utils.SmsUtil;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.mail.MessagingException;
import java.util.List;

@RestController
@RequestMapping("/userLoginAuths")
public class UserLoginAuthsController {

    @Autowired
    private UserLoginAuthsService userLoginAuthsService;

    @Autowired
    private UsersService usersService;


    // （邮箱验证码）生成6位随机数字
    Integer mailCode = (int)((Math.random()*9+1)*100000);

    /**
     * 发送短信验证码
     * @param Phone
     */
    @RequestMapping("/postMsg")
    public boolean postMsg(String Phone) {
        return SmsUtil.postMsg(Phone);
    }

    /**
     * 发送HTML邮件(接收前台传过来的参数:email 收件人地址)
     * @param email
     * @throws MessagingException
     */
    @RequestMapping("/sendMail")
    public boolean sendEmail(String email) throws MessagingException {
        System.out.println(mailCode);
        return userLoginAuthsService.sendEmail(email, mailCode);
    }

    /**
     * 根据识别标识判断手机号或邮箱是否已存在
     * @param identifier
     * @return true表示不存在，false表示已存在
     */
    @GetMapping("/checkIdentifier")
    public boolean checkIdentifier(String identifier) {
        UserLoginAuths userLoginAuth = userLoginAuthsService.findByIdentifier(identifier);
        return userLoginAuth==null?true:false;
    }

    /**
     * 注册，新增用户（角色为普通用户）
     * @param phone 手机号
     * @param code 短信验证码
     * @param credential 密码凭证，此处是站内密码
     * @return
     */
    @PostMapping("/saveByPhone")
    public MyResult saveByPhone(Users user, String phone, String code, String credential) {
        if (SmsUtil.verifyMsg(code, phone)) {
            // 新增用户
            int uId = usersService.save(user);
            // 新增授权
            UserLoginAuths userLoginAuth1 = new UserLoginAuths();
            userLoginAuth1.setUlaCredential(MD5Util.md5(credential));
            userLoginAuth1.setUlaIdentityType("phone");
            userLoginAuth1.setUlaIdentifier(phone);
            userLoginAuth1.setUlaUid(uId);
            userLoginAuthsService.save(userLoginAuth1);
            return new MyResult(200, "根据手机号注册成功",null, null, null, null);
        } else {
            return new MyResult(400, "验证码错误",null, null, null, null);
        }
    }

    /**
     * 注册，新增用户（角色为普通用户）
     * @param email 邮箱
     * @param code 邮箱验证码
     * @param credential 密码凭证，此处是站内密码
     * @return
     */
    @PostMapping("/saveByEmail")
    public MyResult saveByEmail(Users user, String email, Integer code, String credential) throws MessagingException {
        if (code.equals(mailCode)) {
            // 新增用户
            int uId = usersService.save(user);
            // 新增授权
            UserLoginAuths userLoginAuth1 = new UserLoginAuths();
            userLoginAuth1.setUlaCredential(MD5Util.md5(credential));
            userLoginAuth1.setUlaIdentityType("email");
            userLoginAuth1.setUlaIdentifier(email);
            userLoginAuth1.setUlaUid(uId);
            userLoginAuthsService.save(userLoginAuth1);
            return new MyResult(200, "根据邮箱号注册成功",null, null, null, null);
        } else {
            return new MyResult(400, "验证码错误",null, null, null, null);
        }
    }

    /**
     * 根据手机号和验证码登录
     * @param phone
     * @param code
     * @return
     */
    @GetMapping("/loginByPhoneAndCode")
    public MyResult loginByPhoneAndCode(String phone, String code) {
        UserLoginAuths userLoginAuth = userLoginAuthsService.findByIdentifier(phone);
        if (userLoginAuth!=null) {
            boolean bool = SmsUtil.verifyMsg(code, phone);
            if (bool) {
                Users user = usersService.findById(userLoginAuth.getUlaUid());
                // 更改用户上次登录时间
                usersService.updateLastLoginTime(user);
                return new MyResult(200, "使用手机号验证码登录成功", JWTUtil.sign(userLoginAuth.getUlaIdentifier(),
                        userLoginAuth.getUlaCredential()), null, user, null);
            } else {
                return new MyResult(400, "验证码错误",null, null, null, null);
            }
        } else {
            return new MyResult(401, "手机号错误或未被注册",null, null, null, null);
        }
    }

    /**
     * 根据邮箱和验证码登录
     * @param email
     * @param code
     * @return
     */
    @GetMapping("/loginByEmailAndCode")
    public MyResult loginByEmailAndCode(String email, Integer code) {
        UserLoginAuths userLoginAuth = userLoginAuthsService.findByIdentifier(email);
        if (userLoginAuth!=null) {
            if (code.equals(mailCode)) {
                Users user = usersService.findById(userLoginAuth.getUlaUid());
                // 更改用户上次登录时间
                usersService.updateLastLoginTime(user);
                return new MyResult(200, "使用邮箱验证码登录成功", JWTUtil.sign(userLoginAuth.getUlaIdentifier(),
                        userLoginAuth.getUlaCredential()), null, user, null);
            } else {
                return new MyResult(400, "验证码错误",null, null, null, null);
            }
        } else {
            return new MyResult(401, "邮箱错误或者未被注册",null, null, null, null);
        }
    }

    /**
     * 根据识别标识和密码凭证登录
     * @param identifier
     * @param credential
     * @return
     */
    @GetMapping("/loginByIdentifierAndCredential")
    public MyResult loginByIdentifierAndCredential(String identifier, String credential) {
        UserLoginAuths userLoginAuth = userLoginAuthsService.findByIdentifierAndCredential(identifier, MD5Util.md5(credential));
        if (userLoginAuth!=null) {
            Users user = usersService.findById(userLoginAuth.getUlaUid());
            // 更改用户上次登录时间
            usersService.updateLastLoginTime(user);
            return new MyResult(200, "使用密码凭证登录成功", JWTUtil.sign(userLoginAuth.getUlaIdentifier(),
                    userLoginAuth.getUlaCredential()), null, user, null);
        } else {
            return new MyResult(401, "用户名或密码错误",null, null, null, null);
        }
    }

    /**
     * 已注册手机号用户授权绑定邮箱号
     * @param uId
     * @param email
     * @param code
     * @return
     */
    @PostMapping("/addAuthByEmail/{uId}")
    @RequiresRoles(logical = Logical.OR, value = {"admin", "user", "business"})
    public MyResult addAuthByEmail(@PathVariable("uId") Integer uId, String email, Integer code) {
        if (code.equals(mailCode)) {
            // 根据uId新增授权
            UserLoginAuths userLoginAuth1 = new UserLoginAuths();
            userLoginAuth1.setUlaUid(uId);
            userLoginAuth1.setUlaIdentityType("email");
            userLoginAuth1.setUlaCredential(userLoginAuthsService.findByUserId(uId).getUlaCredential());
            userLoginAuth1.setUlaIdentifier(email);
            userLoginAuthsService.save(userLoginAuth1);
            return new MyResult(200, "绑定邮箱号成功",null, null, null, null);
        } else {
            return new MyResult(400, "验证码错误",null, null, null, null);
        }
    }

    /**
     * 已注册邮箱用户授权绑定手机号
     * @param uId
     * @param phone
     * @param code
     * @return
     */
    @PostMapping("/addAuthByPhone/{uId}")
    @RequiresRoles(logical = Logical.OR, value = {"admin", "user", "business"})
    public MyResult addAuthByPhone(@PathVariable("uId") Integer uId, String phone, String code) {
        if (SmsUtil.verifyMsg(code, phone)) {
            // 根据uId新增授权
            UserLoginAuths userLoginAuth1 = new UserLoginAuths();
            userLoginAuth1.setUlaUid(uId);
            userLoginAuth1.setUlaIdentityType("phone");
            userLoginAuth1.setUlaCredential(userLoginAuthsService.findByUserId(uId).getUlaCredential());
            userLoginAuth1.setUlaIdentifier(phone);
            userLoginAuthsService.save(userLoginAuth1);
            return new MyResult(200, "绑定手机号成功",null, null, null, null);
        } else {
            return new MyResult(400, "验证码错误",null, null, null, null);
        }
    }

    /**
     * 判断当前用户的密码凭证是否相等
     * @param uId
     * @return
     */
    @GetMapping("/findPwdByUserId")
    @RequiresRoles(logical = Logical.OR, value = {"admin", "user", "business"})
    public boolean findPwdByUserId(Integer uId, String credential) {
        boolean bool = false;
        List<UserLoginAuths> userLoginAuths = userLoginAuthsService.findAllByUserId(uId);
        for (UserLoginAuths userLoginAuth : userLoginAuths) {
            bool = MD5Util.md5(credential).equals(userLoginAuth.getUlaCredential());
        }
        return bool;
    }

    /**
     * 根据用户id修改登录授权信息中的密码凭证
     * @param userLoginAuth
     * @return
     */
    @RequestMapping("/updateCredential")
//    @RequiresRoles(logical = Logical.OR, value = {"admin", "user", "business"})
    public MyResult updateCredential(UserLoginAuths userLoginAuth) {
        userLoginAuth.setUlaCredential(MD5Util.md5(userLoginAuth.getUlaCredential()));
        // 需要根据用户id修改邮箱和手机号里面的密码
        userLoginAuthsService.updateCredential(userLoginAuth);
        return new MyResult(200, "修改密码成功",null, null, null, null);
    }

    /**
     * 获取识别标识
     * @param identifier
     * @return
     */
    @RequestMapping("/findByIdentifier")
    public MyResult findByIdentifier(String identifier) {
        UserLoginAuths userLogin = userLoginAuthsService.findByIdentifier(identifier);
        if (userLogin!=null) {
            return new MyResult(200, "获取识别标识成功",null, null, userLogin, null);
        } else {
            return new MyResult(400, "此账号不存在",null, null, null, null);
        }
    }

    /**
     * 用户修改密码成功后发送修改密码成功邮件
     * @param email
     * @return
     * @throws MessagingException
     */
    @RequestMapping("/updateEmail")
    public boolean updateEmail(String email) throws MessagingException {
        return userLoginAuthsService.updateEmail(email);
    }

    /**
     * 根据用户id查询该用户的授权登录类型信息
     * （根据授权登录信息判断用户是否绑定其他授权登录方式）
     * @param uId
     * @return
     */
    @GetMapping("/findIdentityTypeByUid/{uId}")
    @RequiresRoles(logical = Logical.OR, value = {"admin", "user", "business"})
    public MyResult findIdentityTypeByUid(@PathVariable("uId") Integer uId) {
        List<UserLoginAuths> userLoginAuths = userLoginAuthsService.findAllByUserId(uId);
        return new MyResult(200, "获取用户的授权登录类型信息成功",null, userLoginAuths, null, null);
    }
}
